#include "gameview.h"
#include "ui_gameview.h"
#include <iostream>

using namespace std;
// 颜色数组 存储每个数字对应的背景色
QColor digitBkg[11] = {QColor::fromRgb(0xEE, 0xE5, 0xDB), QColor::fromRgb(0xEC, 0xE0, 0xC8),
                            QColor::fromRgb(0xF2, 0xAF, 0x78), QColor::fromRgb(0xEE, 0x8A, 0x54),
                            QColor::fromRgb(0xFE, 0x76, 0x5E), QColor::fromRgb(0xE7, 0x58, 0xC),
                            QColor::fromRgb(0xFF, 0x66, 0x66), QColor::fromRgb(0xF1, 0xCF, 0x48),
                            QColor::fromRgb(0xCC, 0x33, 0x33), QColor::fromRgb(0xE3, 0xB9, 0x11),
                            QColor::fromRgb(0xFF, 0x00, 0x00)};

GameView::GameView(QWidget *parent) :
    QWidget(parent,Qt::FramelessWindowHint),
    ui(new Ui::GameView)
{
    ui->setupUi(this);
    resize(400, 600);
    memset(board, 0, sizeof(board));
    setAutoFillBackground(true);
    QPalette pal = palette();
    pal.setColor(QPalette::Background, QColor("#FAF8F0"));
    setPalette(pal);

    titleLabel = new QLabel(tr("2048"), this);
    titleLabel->setStyleSheet("color:#746D65;");
    titleLabel->setFont(QFont("arial", 45, QFont::Black));

    up=new QPushButton("up",this);
    up->setFont(QFont("Arial", 10, QFont::Black));
    up->setGeometry(250, 50, 30, 30);
    connect(up, SIGNAL(clicked()), this, SLOT(gridUp()));

    down=new QPushButton("down",this);
    down->setFont(QFont("Arial", 10, QFont::Black));
    down->setGeometry(250, 150, 30, 30);
    connect(down, SIGNAL(clicked()), this, SLOT(gridDown()));

    left=new QPushButton("left",this);
    left->setFont(QFont("Arial", 10, QFont::Black));
    left->setGeometry(200, 100, 30, 30);
    connect(left, SIGNAL(clicked()), this, SLOT(gridLeft()));

    right=new QPushButton("right",this);
    right->setFont(QFont("Arial", 10, QFont::Black));
    right->setGeometry(300, 100, 30, 30);
    connect(right, SIGNAL(clicked()), this, SLOT(gridRight()));

    start=new QPushButton("start",this);
    start->setFont(QFont("Arial", 20, QFont::Black));
    start->setGeometry(100, 100, 30, 30);
    connect(start, SIGNAL(clicked()), this, SLOT(newStart()));

    closeBtn = new QPushButton("x", this);
    closeBtn->setFocusPolicy(Qt::NoFocus);
    closeBtn->setFont(QFont("Arial", 11, QFont::Normal));
    closeBtn->setStyleSheet("QPushButton{border-style:flat;color:#BDAD9F}"
                        "QPushButton:hover{border-style:flat;color:#FF0000}");
    closeBtn->setCursor(Qt::PointingHandCursor);
    closeBtn->setGeometry(382, 3, 15, 15);
    connect(closeBtn, SIGNAL(clicked()), this, SLOT(close()));

//    number1 = new QLabel(this);
//    number1->setStyleSheet("color:#746D10;");
//    number1->setFont(QFont("arial", 40, QFont::Black));
//    number1->setGeometry(25,200,93,94);
}

GameView::~GameView()
{
    delete ui;
}

void GameView::paintEvent(QPaintEvent *)
{
    // 构造一个QPainter对象 使用它来进行绘图
    QPainter painter(this);
    // 构造一个画刷 颜色为R G B分量分别为141 121 81的颜色
    QBrush brush(QColor::fromRgb(141, 121, 81));
    // 使painter应用这个画刷
    painter.setBrush(brush);

    // 设置画笔为空笔 目的是使绘制的图形没有描边
    painter.setPen(Qt::NoPen);

    // 绘制一个矩形
    painter.drawRect(2,200,396,398);
    // 计算每个小格子的宽度和高度
    w =396, h = 398;
    w = (w - 25) / 4, h = (h - 25) / 4;
    /* 构造一个字体
     * 字体名字为Consolas
     * 字体设置为粗体
     * 字体大小为40像素
     * */
    QFont font;
    font.setFamily("Consolas");
    font.setBold(true);
    font.setPixelSize(40);
    // 使painter应用这个字体
    painter.setFont(font);

    // 循环绘制游戏面板
    for (int i = 0; i < 4; i++)
        for (int j = 0; j < 4; j++)
        {
            // 如果方格中有数字
            if (board[i][j])
            {
                // 设置画刷颜色为数码对应的颜色
                brush.setColor(digitBkg[getBitCount(board[i][j])]);
                // 应用这个画刷
                painter.setBrush(brush);
                // 绘制一个小方格
                painter.drawRect(QRectF(7 + (w + 5) * j, 207 + (h + 5) * i, w, h));
                // 设置画笔为黑色画笔
                painter.setPen(QColor::fromRgb(0, 0, 0));
                // 绘制数码
                painter.drawText(QRectF(7 + (w + 5) * j, 207 + (h + 5) * i, w, h), Qt::AlignCenter,
                                 QString::number(board[i][j]));
                // 设置画笔为空笔
                painter.setPen(Qt::NoPen);
            }
            // 如果方格中没有数字
            else
            {
                // 设置画刷颜色为 RGB分量为171 165 141的颜色
                brush.setColor(QColor::fromRgb(171, 165, 141));
                // 应用这个画刷
                painter.setBrush(brush);
                // 绘制小方格
                painter.drawRect(QRectF(7 + (w + 5) * j, 207 + (h + 5) * i, w, h));
            }
        }
}

int GameView::getBitCount(int n)
{
    // 循环获取数字二进制位数
    int c = 0;
    while (n >>= 1)
        c++;
    // 返回位数-1
    return c - 1;
}

void GameView::generateRandom()  //产生随机数
{
    int zeroNumber = 0;//元素中为零的个数
    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
            if(board[i][j] == 0)
                zeroNumber++;
    }

    if(zeroNumber != 0 && judgeMove == 1)
    {
        judgeMove = 0;
        //srand((unsigned)time(nullptr));
        int newNumber = rand()%10 < 9 ? 2 : 4;   //新随机数的值
        int changePlace = rand()%zeroNumber;  //第changePlace个为0元素将会被替代
        for(int i = 0; i < 4; i++)
        {
            for(int j = 0; j < 4; j++)
            {
                if(board[i][j] == 0)
                {
                    if(changePlace == 0)
                    {
                        board[i][j] = newNumber;
                        changePlace--;

                        break;
                    }
                    else
                        changePlace--;
                }
            }
            if(changePlace < 0)
            {
                break;
            }
        }
    }
}

int GameView::sameElment()   //判断是否有相邻的相等项或=0的项
{
    for (int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 4; j++)
        {
            if(board[i][j]==0)
            {
                return 1;
            }
        }
    }
    for (int i = 0; i < 3; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            if(board[i][j]==board[i][j+1] || board[i][j] == board[i+1][j])
                return 1;
        }
        if(board[i][3] == board[i+1][3])
            return 1;
    }

    return 0;
}


void GameView::changMatrixUp()  //Up修改矩阵元素
{

    for(int i = 0; i < 4; i++)
    {
        for(int k = 0; k < 3; k++)
            for(int j = 3; j > 0; j--)
            {
                if(board[j-1][i] == 0)
                {
                   board[j-1][i] = board[j][i];
                    board[j][i] = 0;
                    if(board[j-1][i] != 0)
                        judgeMove = 1;
                }
            }

    }

    for(int i = 0; i < 4; i++)
    {
        for(int j = 0; j < 3; j++)
        {
            if(board[j][i] == board[j+1][i])
            {
                board[j][i] = board[j][i]*2;
                if(board[j][i] != board[j+1][i])
                    judgeMove = 1;
                switch(j)
                {
                    case 0:
                    {
                        board[j+1][i] = board[j+2][i];
                        board[j+2][i] = board[j+3][i];
                        board[j+3][i] = 0;
                        break;
                    }
                    case 1:
                    {
                        board[j+1][i] = board[j+2][i];
                        board[j+2][i] = 0;
                        break;
                    }
                    case 2:
                    {
                        board[j+1][i] = 0;
                        break;
                    }
                }

            }
        }
    }


}

void GameView::changMatrixDown()  //Down修改矩阵元素
{
    for(int i = 0; i < 4; i++)
    {
        for(int k = 0; k < 3; k++)
            for(int j = 0; j < 3; j++)
            {
                if(board[j+1][i] == 0)
                {
                    board[j+1][i] = board[j][i];
                    if(board[j+1][i] != 0)
                        judgeMove = 1;
                    board[j][i] = 0;
                }
            }

    }

    for(int i = 0; i < 4; i++)
    {
        for(int j = 3; j > 0; j--)
        {
            if(board[j][i] == board[j-1][i])
            {
                board[j][i] = board[j][i]*2;
                if(board[j][i] != board[j-1][i])
                    judgeMove = 1;
                switch(j)
                {
                    case 3:
                    {
                        board[j-1][i] = board[j-2][i];
                        board[j-2][i] = board[j-3][i];
                        board[j-3][i] = 0;
                        break;
                    }
                    case 2:
                    {
                        board[j-1][i] = board[j-2][i];
                        board[j-2][i] = 0;
                        break;
                    }
                    case 1:
                    {
                        board[j-1][i] = 0;
                        break;
                    }
                }
            }
        }

    }

}

void GameView::changMatrixLeft()  //Left修改矩阵元素
{
    int intermediate;
    for(int i = 0; i < 4; i++)
    {
        for(int j = 3; j > i; j--)
        {
            intermediate = board[i][j];
            board[i][j] = board[j][i];
            board[j][i] = intermediate;
        }

    }
    changMatrixUp();
    for(int i = 0; i < 4; i++)
    {
        for(int j = 3; j > i; j--)
        {
            intermediate = board[i][j];
            board[i][j] = board[j][i];
            board[j][i] = intermediate;
        }

    }

}

void GameView::changMatrixRight()  //Right修改矩阵元素
{
    int intermediate;
    for(int i = 0; i < 4; i++)
    {
        for(int j = 3; j > i; j--)
        {
            intermediate = board[i][j];
            board[i][j] = board[j][i];
            board[j][i] = intermediate;
        }

    }
    changMatrixDown();
    for(int i = 0; i < 4; i++)
    {
        for(int j = 3; j > i; j--)
        {
            intermediate = board[i][j];
            board[i][j] = board[j][i];
            board[j][i] = intermediate;
        }

    }

}

void GameView::display()  //显示
{
//    number1->setText(QString::number(board[0][0]));
//    this->ui->label_2->setText(QString::number(gameMatrix[0][1]));
//    this->ui->label_3->setText(QString::number(gameMatrix[0][2]));
//    this->ui->label_4->setText(QString::number(gameMatrix[0][3]));
//    this->ui->label_5->setText(QString::number(gameMatrix[1][0]));
//    this->ui->label_6->setText(QString::number(gameMatrix[1][1]));
//    this->ui->label_7->setText(QString::number(gameMatrix[1][2]));
//    this->ui->label_8->setText(QString::number(gameMatrix[1][3]));
//    this->ui->label_9->setText(QString::number(gameMatrix[2][0]));
//    this->ui->label_10->setText(QString::number(gameMatrix[2][1]));
//    this->ui->label_11->setText(QString::number(gameMatrix[2][2]));
//    this->ui->label_12->setText(QString::number(gameMatrix[2][3]));
//    this->ui->label_13->setText(QString::number(gameMatrix[3][0]));
//    this->ui->label_14->setText(QString::number(gameMatrix[3][1]));
//    this->ui->label_15->setText(QString::number(gameMatrix[3][2]));
//    this->ui->label_16->setText(QString::number(gameMatrix[3][3]));

}

void GameView::newStart()
{
    memset(board, 0, sizeof(board));
    //srand((unsigned)time(nullptr));
    int newNumber = rand()%10 < 9 ? 2 : 4;   //新随机数的值
    int changePlace = rand()%16;  //第changePlace个为0元素将会被替代

    board[changePlace/4][changePlace%4] = newNumber;
     up->setVisible(true);
     down->setVisible(true);
     left->setVisible(true);
     right->setVisible(true);
     start->setVisible(true);
     update();
//    ui->btnUp->setVisible(true);
//    ui->btnDown->setVisible(true);
//    ui->btnLeft->setVisible(true);
//    ui->btnRight->setVisible(true);
//    ui->btnReset->setVisible(true);
//    ui->btnStart->setVisible(false);
}

void GameView::gridUp()
{
    changMatrixUp();
    generateRandom();
    update();

//    if(sameElment() == 0)
//    {
//        rankingList.show();
//    }
}

void GameView::gridDown()
{
    changMatrixDown();
    generateRandom();
    update();

//    if(sameElment() == 0)
//    {
//        rankingList.show();
//    }
}

void GameView::gridLeft()
{
    changMatrixLeft();
    generateRandom();
    update();

//    if(sameElment() == 0)
//    {
//        rankingList.show();
//    }
}

void GameView::gridRight()
{
    changMatrixRight();
    generateRandom();
    update();

//    if(sameElment() == 0)
//    {
//        rankingList.show();
//    }
}
